#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef _MQTT_FUNC_H_
#define _MQTT_FUNC_H_
/***********************************************************************
  *Copyright 2020-03-06, pyfree
  *
  *File Name       : mqttFunc.h
  *File Mark       :
  *Summary         : mqtt数据的编码 解码 加密等业务实现
  *
  *
  *Current Version : 1.00
  *Author          : PengYong
  *FinishDate      :
  *
  *Replace Version :
  *Author          :
  *FinishDate      :

 ************************************************************************/
#include <queue>
#include "datadef.h"
#include "conf_app.h"
#include "queuedata_single.h"

class BusinessDef;
class VerifyForControlCache;

//下控信息结构化描述,由本地接口接收时解析生成
struct ControlFromMqtt
{
	ControlFromMqtt()
		: valCount(0)
		, areaID_(0)
		, devID(0)
		, pID(0)
		, val(0.0)
		, code("")
	{};
	ControlFromMqtt& operator = (const ControlFromMqtt& rhs) //赋值符重载  
	{
		if (this == &rhs)
		{
			return *this;
		}
		valCount = rhs.valCount;
		areaID_ = rhs.areaID_;
		devID = rhs.devID;
		pID = rhs.pID;
		val = rhs.val;
		code = rhs.code;
		return *this;
	};
	int		valCount;	//下发数据个数标记,辅助使用,由本地生成,用于结构化信息传递使用
	int		areaID_;	//区域编号
	long	devID;		//设备编号
	long	pID;		//点编号
	float	val;		//设值
	std::string code;	//如果需要加密校验,其为服务端的hmac_sha计算结果
};
/*
*区域描述信息的全字符串表述,主要在本接口使用,不用每次去业务实例里获取转换
*/
struct AreaDescInfo
{
	AreaDescInfo()
		: areaid(0)
		, areaId("")
		, areaType("")
		, areaName("")
		, areaDesc("")
	{};
	long		areaid;
	std::string areaId;
	std::string areaType;
	std::string areaName;
	std::string areaDesc;
};

class MQTTFUNC
{
public:
	MQTTFUNC();
	~MQTTFUNC();
	//
	inline std::string getAreaID()
	{
		return m_AreaInfo.areaId;
	};
	/**
	 * 生成设备初始信息集
	 * @param bufs {queue } 设备描述信息集合
	 * @return {void}
	 */
	void InitDevsForSend(std::queue<std::string> &bufs);
	/**
	 * 获取上送信息点的json格式描述信息
	 * @param jsonDec {string } 信息点描述信息
	 * @return {void}
	 */
	void getPValueJsonDesc(std::string &jsonDec);
	/**
	 * 帧数据解析
	 * @param buf {const char* } 帧数据
	 * @param len {int } 数据长度
	 * @param mrsfc {ControlFromMqtt& } 来自mqtt下控信息结构化描述,由帧数据解析获得
	 * @return {int} >0成功,<0异常
	 */
	int AddFrame(const char *buf, int len, ControlFromMqtt &mrsfc);
	/**
	 * 如果配置开启了校验功能,需要对下控信息校验,同时进行下控指令创建,并将下控预期验证写入队列
	 * @param mrsfc {ControlFromMqtt& } 来自mqtt下控信息结构化描述,由帧数据解析获得
	 * @return {bool} 是否正确
	 */
	bool CheckFrame(ControlFromMqtt mrsfc);
	/**
	 * hmac_sha加密实现
	 * @param key_ {string } 加密的key
	 * @param temp_ {string } 加密的内容
	 * @return {string} 加密结果
	 */
	std::string hmac_sha_code(std::string key_,std::string temp_);
	/**
	 * 下控信息的加密验证
	 * @param mrsfc {ControlFromMqtt& } 来自mqtt下控信息结构化描述,由帧数据解析获得
	 * @return {bool} 下发加密内容和本地加密结果是否一致
	 */
	bool checkCode(ControlFromMqtt mrsfc);
	/**
	 * 创建下控指令信息
	 * @param mrsfc {ControlFromMqtt& } 来自mqtt下控信息结构化描述,由帧数据解析获得
	 * @return {bool} 是否成功
	 */
	bool createControlCmd(ControlFromMqtt mrsfc);
private:
	/**
	 * 从缓存队列中获取需要上送信息点态势集合
	 * @param its {map<ulong,queue>& } 信息点态势集合
	 * @param sizel {int} 指定一次最大获取信息点的个数
	 * @return {bool} 获取结果是否不为空
	 */
	bool getCacheInfos(std::map<unsigned long long, std::queue<JsonPValue> > &its, int sizel);
private:
	AreaDescInfo m_AreaInfo;						//区域配置信息的全string表述
	BusinessDef *ptr_bdef;							//业务数据集,单体类实例
	QueueDataSingle<SocketMqttWriteItem> *queueforwrite_mqtt;	//由采集端向mqtt服务推送的信息点态势信息缓存队列
	QueueDataSingle<DataToGather> *to_gather_queue;				//向采集端下发的控制信息,可能来自mqtt或阿里云物联网平台等上层应用
	bool ControlCheckFunc;										//是否对来自mqtt服务端的下控信息进行hmac_sha加密校验
	std::string ControlCheckKey;								//进行hmac_sha加密校验key字段
	bool is_Verification;										//是否对下控预期结果进行延迟判定
	VerifyForControlCache *ptr_vcc;								//存储已经进行下控的描述信息单体类实例,用于进行下控预期结果与实际返回结果的判定
};

#endif
